#!/usr/bin/env ruby

=begin
    Blocks are the most interesting and confusing feature of Ruby. Blocks are also known as closures and if you
    are not familiar with Blocks or closures, think of them as anonymous method body.
    As everything in Ruby is an object, a method is also a first class object. And since you can pass around Object
    in between method calls therefore it is possible to pass around methods as normal parameters.
    
    The syntax for doing this is a little different.
    
    a. First you define a method which is going to use the code block. Ruby uses a keyword called 'yield' to execute
    the code block. What that means effectively is to yield control to the code block and resume after the code block
    is finished.
    def my_method
        yield
    end
    
    b. Now call the method with the code block
    my_method { puts "Hello" }
    
    A code block can be enclosed in paranthesis if there is only a single line. Or a do..end block if there are
    multiple lines
    my_method do
        puts "hello"
        puts "world"
    end
    
    It is also possible to pass an argument when yielding the control.
    yield("nauman")
    
    And then to use this parameter in your code block, ruby uses the '|' symbol.
    my_method { |name| puts name }
    
    And similarly to pass an argument to a do..end block, we can write
    my_method do |name|
        puts "Hello, " + name
        puts "How are you today? #{name}"
    end
    
    As with any other method, the last expression evaluated in a code block will be the return value.
    
    *** Blocks are not object, but they can be converted to an object using the class Proc. This can be done
    by using the lambda method of the module Kernel.
    
    prc = lambda { |name| puts "hello, " + name }
    
    and then we can literally pass prc as method parameter
    my_method prc
    
    But here is a difference with the way we call the lambda method, instead of calling yield, we can now invoke
    the 'call' method of the lambda as it is an instance variable of Proc class. So out my_method becomes
    def my_method prc
        prc.call('nauman')
    end
    
=end

line = "Python is a great scripting language, Why can't everyone learn Python and Why is Perl not used anymore"

def my_method prc
    prc.call('ag3nt')
    #yield
end  

 prc = lambda { |name| puts "hello, " + name }
 my_method prc
 





